/*
 * Alice/iVprog
 * 
 * @description First step in orde to run/simulate the working program
 * @see 'edu/cmu/cs/stage3/swing/DialogManager.java' (open the dialog)
 */

package edu.cmu.cs.stage3.alice.authoringtool.util;

public class DefaultScheduler implements Runnable {
   
private static int cont=0;

 private double simFPS = 0.0;
 private int simFrameCount = 0;
 private long simDT = 0;
 private long simLastTime = 0;
 private java.util.Set doOnceRunnables = new java.util.HashSet();
 private java.util.Set eachFrameRunnables = new java.util.HashSet();
 private java.util.Set eachFrameRunnablesMarkedForRemoval = new java.util.HashSet();

private synchronized int contaRun () { int i = 0;
   for (java.util.Iterator iter = eachFrameRunnables.iterator(); iter.hasNext(); ) i++;
   return i; }

 // 'edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool.miscInit(AuthoringTool.java:409)' or
 // 'edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool.worldRun(AuthoringTool.java:1601)'
 public boolean addEachFrameRunnable (Runnable eachFrameRunnable) {
  synchronized (eachFrameRunnables) {
   // try{String str=""; System.out.println(str.charAt(3));}catch(Exception e){e.printStackTrace();}
   //boolean bool = eachFrameRunnables.add(eachFrameRunnable); //
   System.out.println("DefaultScheduler.java: addEachFrameRunnable("+eachFrameRunnable+")"); // #eachFrameRunnables="+(contaRun()+1));
   //return bool;
   // 'edu.cmu.cs.stage3.alice.authoringtool.util.OneShotScheduler' & 'edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool'
   return eachFrameRunnables.add(eachFrameRunnable); //
   }
  }

 public boolean removeEachFrameRunnable (Runnable eachFrameRunnable) {
  synchronized (eachFrameRunnablesMarkedForRemoval) {
   return eachFrameRunnablesMarkedForRemoval.add(eachFrameRunnable);
   }
  }

 public Runnable[] getEachFrameRunnables () {
  synchronized (eachFrameRunnables) {
   Runnable [] runnables = new Runnable[eachFrameRunnables.size()];
   int i = 0;
   for (java.util.Iterator iter = eachFrameRunnables.iterator(); iter.hasNext(); ) {
    runnables[i++] = (Runnable)iter.next();
    }
   return runnables;
   }
  }

 // src/edu/cmu/cs/stage3/alice/authoringtool/util/DefaultScheduler.java: run()
 //  at edu.cmu.cs.stage3.scheduler.AbstractScheduler.run(AbstractScheduler.java:46): 'eachFrameRunnable[_i].run()'
 //  at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
 public void run () {
  // System.out.println("DefaultScheduler.java: run()");
  simulateOnce();
  }

 // at edu.cmu.cs.stage3.alice.core.clock.DefaultClock.schedule(DefaultClock.java:72)
 // at edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool$6.run(AuthoringTool.java:418)
 // at edu.cmu.cs.stage3.alice.authoringtool.util.DefaultScheduler.simulateOnce(DefaultScheduler.java:83)
 // at edu.cmu.cs.stage3.alice.authoringtool.util.DefaultScheduler.run(DefaultScheduler.java:50)
 // at edu.cmu.cs.stage3.scheduler.AbstractScheduler.run(AbstractScheduler.java:79)

 //static int cont=0;
 synchronized private void simulateOnce () {
  //if (cont==0) System.out.println("DefaultScheduler.java: simulateOnce(): #doOnceRunnables="+doOnceRunnables.size()+" #eachFrameRunnablesMarkedForRemoval="+eachFrameRunnablesMarkedForRemoval.size());
  //T if (cont==0){try{String str=""; if (cont==0) System.out.println(str.charAt(3));}catch(Exception e){e.printStackTrace();}
  //T System.out.println("DefaultScheduler.java: simulateOnce(): inicio"); } else System.out.print("."); cont++;
  for (java.util.Iterator iter = doOnceRunnables.iterator(); iter.hasNext(); ) {
   Runnable runnable = (Runnable)iter.next();
   // if (cont==0) {System.out.println("DefaultScheduler.java: simulateOnce(): 1: "+cont+": "+runnable); cont=1; }
   try {
    runnable.run();
   } catch (Throwable t) {
    System.err.println("Error during simulation: DefaultScheduler.java: ");
    t.printStackTrace();
    }
   iter.remove();
   }

  for (java.util.Iterator iter = eachFrameRunnablesMarkedForRemoval.iterator(); iter.hasNext(); ) {
   eachFrameRunnables.remove( iter.next() );
   }
  eachFrameRunnablesMarkedForRemoval.clear();

  for (java.util.Iterator iter = eachFrameRunnables.iterator(); iter.hasNext(); )
   try {
    Runnable runnable = (Runnable)iter.next();
    try { // 'runnable' is 'edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool' or 'edu.cmu.cs.stage3.alice.authoringtool.util.OneShotScheduler'
     runnable.run(); // came first from 'edu.cmu.cs.stage3.scheduler.AbstractScheduler.run(AbstractScheduler.java:95)'
    } catch (Throwable t) {
     System.err.println("Error: DefaultScheduler.java: during simulation: "+t.toString());
     t.printStackTrace();
     }
   } catch (Exception e) {
    System.err.println("Error: DefaultScheduler.java: during simulation: "+e.toString());
    e.printStackTrace();
    return;
    }

  long time = System.currentTimeMillis();
  simDT += time - simLastTime;
  simLastTime = time;

  simFrameCount++;
  if ((simFrameCount == 5) || (simDT > 500)) {
   simFPS = (simFrameCount)/(simDT*.001);
   simFrameCount = 0;
   simDT = 0;
   }
  }

 public double getSimulationFPS () {
  return simFPS;
  }

 }
